import pyjd

from pyjamas.ui.RootPanel import RootPanel
from pyjamas.ui.Label import Label
from pyjamas.ui.Button import Button
from pyjamas.ui.HTML import HTML
from pyjamas.ui.VerticalPanel import VerticalPanel
from pyjamas.ui.TextBox import TextBox
from pyjamas.ui.RadioButton import RadioButton
from pyjamas.JSONService import JSONProxy
from pyjamas.JSONParser import JSONParser
from __pyjamas__ import JS
import pyjamas
import random


class ProblemPage:
    def onModuleLoad(self):
               
        loc = pyjamas.Window.getLocation()
        getVars = loc.getSearchDict()
        self.seed = int(getVars['seed'])
        
        self.problem = "cgi-bin/problems/" + getVars['problem'] + ".txt"
        self.showAnswer = getVars['showAnswer']
        self.showSolution = getVars['showSolution']
        self.maxAttempts = int(getVars['maxAttempts'])
       
        '''Manually set for debugging
        #self.seed = 6
        #self.problem = "cgi-bin/problems/problem2.txt"
        self.showAnswer = True
        self.showSolution = False
        self.maxAttempts = 1'''
        self.debug = False
        
        self.RemoteService = RemoteService()
        self.parser = JSONParser()
        self.status = Label()
        self.panel = VerticalPanel()
        self.panel.add(self.status)
        RootPanel().add(self.panel)
        
        self.RemoteService.getProblem(self.seed, self.problem, self)
        
        
    def onRemoteResponse(self, response, request_info):
        
        if(self.debug == True):
            self.status.setText(response)
            
        self.response = self.parser.decodeAsObject(response)
        if (self.response[0] == "getProblem"):
            self.problemData = self.response
            self.dvlabels = []
            self.answerWidgets = []
            self.submitButtons = []
            self.solutionlabel = []
            self.attemptsRemaining = []
            self.variables = self.problemData[4]
            
            for index, item in enumerate(self.problemData[1]):
                problemText = HTML(item)
                self.panel.add(problemText)
                
                if(self.problemData[2][index] != "multi"):
                    self.attemptsRemaining.append(self.maxAttempts) 
                else:               
                    self.attemptsRemaining.append(1) 
                    
                '''Add the dynamic viewing space if needed'''
                dvlabel = HTML()
                if (self.problemData[2][index] == "multi"):
                    dvlabel.setHeight("0px")
                else:
                    dvlabel.setHeight("45px")
                    
                self.dvlabels.append(dvlabel)
                self.panel.add(dvlabel)
                
                if (self.problemData[2][index] == "multi"):
                    
                    choicePanel = VerticalPanel()
                    
                    for item in self.problemData[3][index]:
                        rbutton = RadioButton(index)
                        item = item.replace("<p>", "")
                        item = item.replace("</p>", "")
                        rbutton.setHTML(item)
                        choicePanel.add(rbutton)
                    
                    self.answerWidgets.append(choicePanel)
                    self.panel.add(choicePanel)
                else:
                    textbox = TextBox()
                    textbox.setWidth("200px")
                    textbox.setHeight("55px")
                    textbox.addKeyboardListener(TextBoxListener(self, textbox, dvlabel))
                    self.answerWidgets.append(textbox)
                    self.panel.add(textbox)
                
                button = Button("Submit", getattr(self, "onClick"))
                self.submitButtons.append(button)  
                self.panel.add(button)
                
                
                solLabel = HTML()
                self.solutionlabel.append(solLabel)
                self.panel.add(solLabel)
                
            
        elif (self.response[0] == "checkSolution"):
            self.lastSolutionData = self.response
            
            if (self.lastSolutionData[1] == True):
                self.solutionlabel[self.lastChecked].setHTML("Correct!")
            elif (str(self.lastSolutionData[1]) == "Invalid Answer"):
                self.solutionlabel[self.lastChecked].setHTML("Invalid Answer")
            else:
                if(self.attemptsRemaining[self.lastChecked] > 0):
                    self.solutionlabel[self.lastChecked].setHTML("Incorrect! " + str(self.attemptsRemaining[self.lastChecked]) + " attempts remaining.")
                else:
                    self.solutionlabel[self.lastChecked].setHTML("Incorrect!")
                    
                if(bool(self.showAnswer) == True and self.attemptsRemaining[self.lastChecked] <= 0):
                    self.solutionlabel[self.lastChecked].setHTML(self.solutionlabel[self.lastChecked].getHTML() + "<br />" + self.lastSolutionData[2])
                if(bool(self.showSolution) == True and self.attemptsRemaining[self.lastChecked] <= 0):
                    self.solutionlabel[self.lastChecked].setHTML(self.solutionlabel[self.lastChecked].getHTML() + "<br />" + self.lastSolutionData[3])
                    
        elif (self.response[0] == "renderPreview"):
            if(self.response[2] == ""):
                self.dvlabels[self.response[1]].setHTML("")
            else:
                self.dvlabels[self.response[1]].setHTML("<div class='math'><i>Preview:</i>" + self.response[2] + "</div>")
            
        JS("""$wnd.jsMath.ProcessBeforeShowing();""")
        
    def onRemoteError(self, code, errobj, request_info):
        # onRemoteError gets the HTTP error code or 0 and
        # errobj is an jsonrpc 2.0 error dict:
        #     {
        #       'code': jsonrpc-error-code (integer) ,
        #       'message': jsonrpc-error-message (string) ,
        #       'data' : extra-error-data
        #     }
        message = errobj['message']
        if code != 0:
            self.status.setText("HTTP error %d: %s" % 
                                (code, message))
        else:
            code = errobj['code']
            self.status.setText("JSONRPC Error %s: %s" %
                                (code, message))
    
    
    
    def onClick(self, sender):
        
        index = 0
        for item in self.submitButtons:
            if (sender == item):
                break;
            else:
                index += 1
                
        self.attemptsRemaining[index] = self.attemptsRemaining[index]-1;
                
        self.lastChecked = index
        
        if (self.problemData[2][index] != "multi"):
            self.RemoteService.checkSolution(self.seed, self.problem, index, self.variables, self.parser.encode(self.answerWidgets[index].getText()), self)
        else:
            radiobuttons = self.answerWidgets[index].getChildren()
            for itemIndex, item in enumerate(radiobuttons):
                answer = HTML(self.problemData[3][index][itemIndex]).getText()
                answer = answer.replace("\n", "")
                answer = self.parser.encode(answer)
                if item.isChecked() == True:
                    self.RemoteService.checkSolution(self.seed, self.problem, index, self.variables, answer, self)
                    break
    
    def updateText(self, text, echo):
        index = 0
        for item in self.dvlabels:
            if (item == echo):
                break;
            else:
                index += 1
        self.RemoteService.renderPreview(index, text.getText(), self)
        
       
class TextBoxListener:
    def __init__(self, parent, textBox, echo):
        self.textBox=textBox
        self.echo=echo
        self.parent=parent
        
    def onClick(self, sender):
        pass
    
    def onKeyUp(self, sender, keyCode, modifiers):
        self.parent.updateText(self.textBox, self.echo)

    def onKeyDown(self, sender, keyCode, modifiers):
        pass
    
    def onKeyPress(self, sender, keyCode, modifiers):
        pass

class RemoteService(JSONProxy):
    def __init__(self):
        JSONProxy.__init__(self, "../cgi-bin/Service.py", ["renderPreview", "getProblem", "checkSolution"])

if __name__ == '__main__':
    pyjd.setup("http://127.0.0.1/output/ProblemPage.html")
    app = ProblemPage()
    app.onModuleLoad()
    pyjd.run()